#include <stdint.h>
#include <stdatomic.h>
#include <stdlib.h>

// 匹配 Java Random 类的常量（java.util.Random）
#define MULTIPLIER 0x5DEECE66DL
#define ADDEND 0xBL
#define MASK ((1L << 48) - 1)

/**
 * 随机数生成器结构体（模拟 Java 中的 Random 类）
 * 成员：
 *   seed: 原子长整型，对应 Java 的 AtomicLong seed
 */
typedef struct {
    atomic_ullong seed;  // 使用无符号 64 位原子类型，适配 48 位种子
} RandomGenerator;

/**
 * 初始化随机数生成器
 * @param gen: 生成器实例指针
 * @param initial_seed: 初始种子（Java 中会做 (seed ^ multiplier) & mask 处理）
 */
void random_generator_init(RandomGenerator *gen, uint64_t initial_seed) {
    if (gen == NULL) {
        return;
    }
    // 匹配 Java Random 构造函数的种子初始化逻辑
    uint64_t init_seed = (initial_seed ^ MULTIPLIER) & MASK;
    atomic_init(&gen->seed, init_seed);
}

/**
 * 生成指定位数的随机数（对齐 Java 的 next(int bits) 方法）
 * @param gen: 生成器实例指针
 * @param bits: 需要的随机位数（1~32）
 * @return: 对应位数的随机整数
 */
int32_t random_generator_next(RandomGenerator *gen, int bits) {
    if (gen == NULL || bits < 1 || bits > 32) {
        return 0;  // 非法参数返回默认值
    }

    uint64_t oldseed, nextseed;
    atomic_ullong *seed = &gen->seed;

    // CAS 循环：匹配 Java 的 do-while 逻辑
    do {
        oldseed = atomic_load(seed);  // 对应 seed.get()
        // 计算新种子：(oldseed * multiplier + addend) & mask
        nextseed = (oldseed * MULTIPLIER + ADDEND) & MASK;
    } while (!atomic_compare_exchange_weak(seed, &oldseed, nextseed));
    // atomic_compare_exchange_weak 对应 Java 的 compareAndSet

    // 无符号右移 (48 - bits) 位，转换为 32 位整数
    return (int32_t)(nextseed >> (48 - bits));
}

// 示例测试代码
#include <stdio.h>
#include <pthread.h>

// 测试：单线程生成随机数
void test_single_thread() {
    RandomGenerator gen;
    // 初始种子使用 12345（可自定义）
    random_generator_init(&gen, 12345);

    printf("单线程随机数（bits=32）：\n");
    for (int i = 0; i < 5; i++) {
        int32_t rand_val = random_generator_next(&gen, 32);
        printf("%d\n", rand_val);
    }
}

// 多线程测试：每个线程生成 3 个随机数
#define THREAD_NUM 3
void* thread_func(void *arg) {
    RandomGenerator *gen = (RandomGenerator*)arg;
    long tid = (long)arg - (long)gen;  // 简单生成线程 ID
    printf("线程 %ld 随机数：\n", tid);
    for (int i = 0; i < 3; i++) {
        int32_t rand_val = random_generator_next(gen, 32);
        printf("线程 %ld: %d\n", tid, rand_val);
    }
    return NULL;
}

void test_multi_thread() {
    RandomGenerator gen;
    random_generator_init(&gen, 67890);

    pthread_t threads[THREAD_NUM];
    for (long i = 0; i < THREAD_NUM; i++) {
        pthread_create(&threads[i], NULL, thread_func, &gen);
    }

    for (int i = 0; i < THREAD_NUM; i++) {
        pthread_join(threads[i], NULL);
    }
}

int main() {
    test_single_thread();
    printf("------------------------\n");
    test_multi_thread();
    return 0;
}